#include <QApplication>
#include "server.h"
#include "gate.h"
#include "client.h"
#include "logindialog.h"
#include <QFile>
#include <QTranslator>
#include "framework.h"
#include "sysclientheartbeat.h"
#include "sysclientsocket.h"
#include "userconfigs.h"
#include "systimer.h"
#include "sysbreakpad.h"

CNS_SYS_REGISTER(SysClientSocket)
CNS_SYS_REGISTER(SysClientHeartbeat)
CNS_SYS_REGISTER(SysTimer)
CNS_SYS_REGISTER(SysBreakpad)

Framework *g_fwClient = nullptr;
Client::Client()
{
    _clientSocketProc = FRAMEWORK->getComponent("/client/.//clientSocket").staticCast<ClientSocketProc>();
    start();
}

void setStyle(const QString &fileName)
{
    if (!fileName.isEmpty()) {
        QFile file(fileName);

        if (file.open(QFile::ReadOnly)) {
            QString str = file.readAll();
            QString paletteColor = str.mid(20, 7);
            qApp->setPalette(QPalette(QColor(paletteColor)));
            qApp->setStyleSheet(str);
        }
    }
}

int main(int argc, char *argv[])
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,6,0))
    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
    QApplication app(argc, argv);
    gCnsLogger = new CnsLogger();
    FRAMEWORK = new Framework();
    FRAMEWORK->readComDefinition("cns/client");
    Server server;
    Gate   gate;
    Client client;

    QObject::connect(&app, &QGuiApplication::lastWindowClosed, \
                     &app, [&](){
        server.close();
        gate.close();
        client.close();
        server.wait();
        gate.wait();
        client.wait();
    });
    QTranslator translator_zh_CN;

    translator_zh_CN.load("config/cns_zh_CN");
    app.installTranslator(&translator_zh_CN);
    setStyle(":/qss/black.css");

    UserConfigsPtr userConfigs = FRAMEWORK->getComponent("/client/.//userConfigs").staticCast<UserConfigs>();
    userConfigs->settings_init();

    CnsComponentPtr view = FRAMEWORK->getComponent("/client/.//login");
    view->exec("start");

    return app.exec();
}

void Client::close()
{
    uv_async_send(_clientSocketProc->getAsync());
}

void Client::run()
{
    uv_loop_t *loop = uv_loop_new();
    _clientSocketProc->exec("run", Q_ARG(uv_loop_t*, loop));
    uv_run(loop, UV_RUN_DEFAULT);
    uv_loop_close(loop);
    free(loop);
}
